// -*- mode: c++ -*-
#ifndef __transitiontarget_h__
#define __transitiontarget_h__
#include <list>
#include <vector>
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>

using namespace std;

class Transition;
class TransitionTarget;
typedef std::list<Transition> TransitionList;
typedef std::vector<Transition*> TList;
typedef std::list<TransitionTarget*> TargetList;
typedef std::vector<std::string> strvec;
typedef std::set<std::string> strset;
typedef boost::shared_ptr<TransitionTarget> TtPtr;
typedef std::map<std::string, TransitionTarget*> TtMap;
typedef std::set<TransitionTarget> TtSet;
typedef std::set<std::string>  strset;




class TransitionTarget 
{
public:
    enum TtType {Atomic, Compound, Parallel, History, Final};

    TransitionTarget( std::string id, TransitionTarget *parent = NULL);
    ~TransitionTarget();

    std::string id;
    TtPtr parent;
    //TtMap m_children;
    TransitionList transitions;
    TargetList children;
    strvec initial;
    strvec initialTransition;
    bool m_active;
    TtType type;
    virtual void onEntry();
    virtual void onExit();

    TransitionList *getTransitionList(std::string const event);
    void setInitial(std::string target);
    bool start(strset &cfg);	// get initial config.
    bool isAncestor(TransitionTarget *s);
    
    int operator ==(const TransitionTarget &rhs)
	{
	    return id == rhs.id;
	};

    friend ostream &operator<<(ostream& s, const TransitionTarget* c);
    bool isCompound(void)
	{
	    return type==Compound;
	}
    
    bool isParallel(void)
	{
	    return type == TransitionTarget::Parallel;
	};

    bool isAtomic(void)
	{
	    return type == TransitionTarget::Atomic;
	}
    bool isFinal(void)
	{
	    return type == TransitionTarget::Final;
	}
};

struct eq{
    eq(const TransitionTarget* obj) : obj_(obj) { }
    bool operator()(TransitionTarget *c1) const {return  c1->id == obj_->id;}  
private:
    const TransitionTarget* obj_;
};

#endif
